package com.yixing.tech.entity.entity.attr;

import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.common.base.ConditionsVO;
import com.yixing.tech.entity.entity.CustomActionParam;
import com.yixing.tech.entity.entity.RequestType;
import com.yixing.tech.common.vo.s5.EntitySchema;
import com.yixing.tech.entity.service.EntityBaseService;
import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yixing tech
 * at 2021/10/9
 * describe：
 */
@Data
public class AttrType {
    String name;
    String code;

    public AttrType(String n, String c) {
        name = n;
        code = c;
    }

    public static AttrType build(String code) {
        if (null == code) return new SingleText();
        switch (code) {
            case "dict":
                return new Dict();
            case "dictArray":
                return new DictArray();
            case "address":
                return new Address();
            case "obj":
                return new Obj();
            case "multiText":
                return new MultiText();
            case "objAttr":
                return new ObjAttr();
            case "digitalText":
                return new DigitalText();
            case "emailText":
                return new EmailText();
            case "objTemplate":
                return new ObjTemplate();
            case "objArray":
                return new ObjArray();
            case "user":
                return new User();
            case "userGroup":
                return new UserGroup();
            case "timeText":
                return new TimeText();
            case "phoneText":
                return new PhoneText();
            case "switchText":
                return new SwitchText();
            case "binaryText":
                return new BinaryText();
            case "role":
                return new Role();
            case "multiObject":
                return new MultiObject();
            case "signature":
                return new Signature();
            case "ID":
                return new ID();
            case "relationalEvent":
                return new RelationalEvent();
            case "richText":
                return new RichText();
            case "department":
                return new Department();
            case "videoUrl":
                return new VideoUrl();
            case "formulas":
                return new FormulasText();
            case "objList":
                return new ObjList();
            case "insertEvent":
                return new InsertEvent();
            case "updateEvent":
                return new UpdateEvent();
            case "arraySubObj":
                return new ArraySubObj();
            case "timeStatus":
                return new TimeStatus();
            case "webLink":
                return new WebLink();
            case "location":
                return new Location();
            case "splitObj":
                return new SplitObj();
            case "subObj":
                return new SubObj();
            case "customOp":
                return new CustomOp();
            case "picture":
                return new Picture();
            default:
                return new SingleText();
        }
    }

    /**
     * 数据检索处理
     *
     * @param operations
     * @param attr
     * @throws BusinessException
     */
    public void out(List<AggregationOperation> operations, EntitySchema.AttrVO attr) throws BusinessException {

    }

    /**
     * 数据检索处理
     *
     * @param operations
     * @param attr
     * @throws BusinessException
     */
    public void out(List<AggregationOperation> operations, EntitySchema.AttrVO attr, RequestType requestType) throws BusinessException {

    }

    /**
     * 数据插入处理
     * @param source
     * @param attr
     * @return
     * @throws BusinessException
     */
    public Object in(Object source, EntitySchema.AttrVO attr) throws BusinessException {
        return source;
    }

    /**
     * objectId数据转换
     */
     protected final Object inWithList(Object source) throws BusinessException {
         if (ObjectUtils.isEmpty(source)) return source;
         if (source instanceof List) {
             List<?> l = (List) source;
             return l.stream().map(m -> new ObjectId(m.toString())).collect(Collectors.toList());
         } else {
             List<ObjectId> list = new ArrayList<>();
             list.add(new ObjectId(source.toString()));
             return list;
         }
    }

    /**
     * 过滤条件处理
     */
    public void condition(ConditionsVO.Condition cond, EntitySchema.AttrVO attr) throws BusinessException {

    }

    /**
     * 行为
     */
    public void exeAction(CustomActionParam param, List<EntitySchema.AttrVO> attrs) throws BusinessException {

    }

    /**
     * 值包装，不同属性类型的值需要进行包装，比如字典的名称或者编码会包装成字典对象
     *
     * @return 默认返回原始值
     * @throws BusinessException
     */
    public Object wrapValue(EntitySchema.AttrVO attr, Object value, MongoTemplate mongoTemplate,
                            EntityBaseService ebs, String tenantId) throws BusinessException {
        return value;
    }
}
